package com.leyou.item.service.impl;

import com.leyou.common.constant.MessageConstant;
import com.leyou.common.enums.ItemExceptionEnum;
import com.leyou.common.exceptions.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.utils.JsonUtils;
import com.leyou.dto.SpecGroupDto;
import com.leyou.item.entity.SpecGroup;
import com.leyou.item.entity.SpecParam;
import com.leyou.item.entity.SpuDetail;
import com.leyou.item.mapper.SpecGroupMapper;
import com.leyou.item.mapper.SpecParamMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.service.SpecGroupService;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @version V1.0
 * @author: Ljxpa
 * @date: 2020/03/06 23:25
 * @description:
 */
@Service
@Slf4j//使用日志的注解
public class SpecGroupServiceImpl implements SpecGroupService {

	@Autowired
	private SpecGroupMapper specGroupMapper;

	@Autowired
	private SpuMapper spuMapper;

	@Autowired
	private SpecParamMapper specParamMapper;

	/**
	 * 添加规格参数组
	 * @param specGroupDto 前端传递的name cid
	 */
	@Override
	@Transactional
	public void addGroup(SpecGroupDto specGroupDto) {
		SpecGroup specGroup = BeanHelper.copyProperties(specGroupDto, SpecGroup.class);
		specGroup.setCreateTime(DateTime.now().toDate());
		int count = specGroupMapper.insert(specGroup);
		if (count != 1) {
			throw new LyException(ItemExceptionEnum.DATA_SAVE_ERROR);
		}
	}

	/**
	 * 根据品类id查询该品类下所有参数组
	 *
	 * @param cid 品类id
	 * @return dto集合
	 */
	@Override
	public List<SpecGroupDto> queryGroupsByCid(Long cid) {
		Example example = new Example(SpecGroup.class);
		example.createCriteria().andEqualTo("cid", cid);
		List<SpecGroup> specGroups = null;
		try {
			specGroups = specGroupMapper.selectByExample(example);
		} catch (Exception e) {
			log.info(MessageConstant.QUERY_SPECGROUP_DB_ERROR);
			// e.printStackTrace();
		}
		if (CollectionUtils.isEmpty(specGroups)) {
			throw new LyException(ItemExceptionEnum.SPECGROUP_NOT_FOUND);
		}
		/*List<SpecGroupDto> collect = specGroups.stream().map(new Function<SpecGroup, SpecGroupDto>() {
			@Override
			public SpecGroupDto apply(SpecGroup specGroup) {
				SpecGroupDto specGroupDto = new SpecGroupDto();
				BeanUtils.copyProperties(specGroup,specGroupDto);
				return specGroupDto;
			}
		}).collect(Collectors.toList());*/
		return BeanHelper.copyWithCollection(specGroups, SpecGroupDto.class);
	}

	/**
	 * 修改规格组信息
	 * @param specGroupDto 前端提交的dto对象
	 */
	@Override
	@Transactional
	public void editSpecGroup(SpecGroupDto specGroupDto) {
		SpecGroup specGroup = BeanHelper.copyProperties(specGroupDto, SpecGroup.class);
		specGroup.setUpdateTime(DateTime.now().toDate());
		specGroup.setUpdateTime(DateTime.now().toDate());
		try {
			int count = specGroupMapper.updateByPrimaryKey(specGroup);
			if (1 != count) {
				throw new LyException(ItemExceptionEnum.DATA_UPDATE_ERROR);
			}
		} catch (Exception e) {
			log.error(MessageConstant.UPDATE_SPECGROUP_ERROR);
		}
	}

	/**
	 * 根据组id删除规格参数组，先判断是否有spu引用，组内是否有参数，只有两者都是否的情况下才允许删除
	 * @param gid 规格参数组的id
	 */
	@Override
	@Transactional
	public void delSpecGroupById(Long gid) {
		//先查询是否已经有spu使用该参数组，如果有，则提示不能删除
		SpecGroup specGroup = specGroupMapper.selectByPrimaryKey(gid);
		//根据参数组id查询组内所有的规格参数
		SpecParam specParam = new SpecParam();
		specParam.setGroupId(gid);
		List<SpecParam> selecParamList = specParamMapper.select(specParam);

		//根据品类id查询该品类下是否有spu
		SpuDetail spuDetail = spuMapper.querySpuDetailByCid(specGroup.getCid());
		if (null != spuDetail) {
			//有spu，遍历spu是否引用了该参数组
			Map<Long, String> map = JsonUtils.toMap(spuDetail.getGenericSpec() + spuDetail.getSpecialSpec(), Long.class, String.class);
			for (SpecParam param : selecParamList) {
				if (map.containsKey(param.getId())) {
					//如果spu中使用了规格参数，则不能删除
					throw new LyException(ItemExceptionEnum.DATA_NOT_ALLOW_DELETE);
				}
			}
		}

		//如果组内有参数不允许删除
		if (selecParamList.size() > 0) {
			throw new LyException(ItemExceptionEnum.DATA_NOT_ALLOW_DELETE);
		}

		//没有spu引用，组内没有参数，直接删除
		int i = specGroupMapper.deleteByPrimaryKey(gid);
		if (1 != i) {
			throw new LyException(ItemExceptionEnum.DATA_DELETE_ERROR);
		}
	}
}
